#include "ZComDef.h"
#include "OSAL.h"
#include "AF.h"
#include "ZDApp.h"
#include "ZDObject.h"
#include "ZDProfile.h"
#include "hal_uart.h"
#include "vcomUart.h"

// 0xA5, SIZE, CMD,
#define  UART_RXSTA_IDLE     0
#define  UART_RXSTA_START    1
#define  UART_RXSTA_PAYLOAD  2
#define  UART_RXSTA_ERRO     3

#define  UART_CMD_SFD        0xFE

typedef struct
{
  uint8 len;
  uint8 count;
  uint8 payload[];
}cmd_uartRxBuf_t;

void cmd_Rx(uint8 port);
void cmd_Tx(uint8 port);
void cmd_RxBuf(uint8 get_byte);

uint8 cmd_TaskId = 0xFF;

uint8 cmd_RxSta = UART_RXSTA_IDLE;
cmd_uartRxBuf_t* cmd_uartRxBuf = NULL;

void cmd_uartInit(uint8 taskId)
{
  halUARTCfg_t uartConfig;
  /* Initialize APP ID */
  cmd_TaskId = taskId;

  /* UART Configuration */
  uartConfig.configured           = TRUE;
  uartConfig.baudRate             = HAL_UART_BR_57600;
  uartConfig.flowControl          = FALSE;
  uartConfig.flowControlThreshold = 32;
  uartConfig.rx.maxBufSize        = 0;
  uartConfig.tx.maxBufSize        = 0;
  uartConfig.idleTimeout          = 4;
  uartConfig.intEnable            = TRUE;
  uartConfig.callBackFunc         = cmd_UartHandle;
  HalUARTOpen (HAL_UART_PORT_0, &uartConfig);
}

void cmd_UartHandle ( uint8 port, uint8 event )
{
  if (event & ( HAL_UART_RX_FULL | HAL_UART_RX_ABOUT_FULL | HAL_UART_RX_TIMEOUT))
  {
    cmd_Rx(port);
  }
  if (event == HAL_UART_TX_EMPTY)
  {
    cmd_Tx(port);
  }
}

void cmd_Rx(uint8 port)
{
  uint8 get_byte;
  while( HalUARTRead( port, &get_byte, 1) )
  {
    cmd_RxBuf( get_byte );
  }
  
  
}

void cmd_Tx(uint8 port)
{
  
}

void cmd_RxBuf( uint8 get_byte )
{
  switch( cmd_RxSta )
  {
  case UART_RXSTA_IDLE:
    if(get_byte == UART_CMD_SFD)
    {
      cmd_RxSta = UART_RXSTA_START;
    }
    break;

  case UART_RXSTA_START:
    if( (get_byte >= 3) && (get_byte <= 128) )
    {
      uint8 len = get_byte;
      cmd_uartRxBuf = osal_mem_alloc( sizeof(cmd_uartRxBuf_t) + len );
      if( cmd_uartRxBuf )
      {
        cmd_uartRxBuf->count = 0;
        cmd_uartRxBuf->len = len;
        cmd_RxSta = UART_RXSTA_PAYLOAD;
      }
    }
    
  case UART_RXSTA_PAYLOAD:
    {
      cmd_uartRxBuf->payload[cmd_uartRxBuf->count] = get_byte;
    }
  }
}
